class GameTester {
    constructor() {
        this.game = new GameClient(true);  // Create game instance in test mode
        this.testResults = {
            passed: 0,
            failed: 0,
            tests: []
        };
    }

    async runAllTests() {
        console.log('Starting automated game tests...');
        
        try {
            await this.testMazeGeneration();
            await this.testSnakeMovement();
            await this.testCollisionDetection();
            await this.testFoodSystem();
            await this.testEnergySystem();
            await this.testAIBehavior();
        } catch (error) {
            console.error('Test error:', error);
        }
        
        this.reportResults();
    }

    async testMazeGeneration() {
        const testCases = ['small', 'medium', 'large', 'ultra'];
        
        for (const size of testCases) {
            try {
                this.game.mazeSize = size;
                this.game.generateMaze(this.game.mazeSizes[size].size);
                
                const hasCorrectSize = this.game.currentMaze.length === this.game.mazeSizes[size].size;
                const hasValidWalls = this.validateMazeWalls(this.game.currentMaze);
                
                this.assertTest(
                    `Maze Generation (${size})`,
                    hasCorrectSize && hasValidWalls,
                    `Maze should have correct size and valid walls`
                );
            } catch (error) {
                this.logTestFailure(`Maze Generation (${size})`, error);
            }
        }
    }

    async testSnakeMovement() {
        try {
            this.game.resetGame();
            const initialPos = {...this.game.snake.position};
            
            // Test each direction
            const directions = ['up', 'right', 'down', 'left'];
            for (const dir of directions) {
                this.game.snake.direction = dir;
                const oldPos = {...this.game.snake.position};
                this.game.moveSnake();
                
                const moved = this.verifyMovement(oldPos, this.game.snake.position, dir);
                this.assertTest(
                    `Snake Movement (${dir})`,
                    moved,
                    `Snake should move correctly in ${dir} direction`
                );
            }
        } catch (error) {
            this.logTestFailure('Snake Movement', error);
        }
    }

    async testCollisionDetection() {
        try {
            this.game.resetGame();
            
            // Test wall collision
            const wallCollision = this.game.checkCollision({x: -1, y: 0});
            this.assertTest(
                'Wall Collision Detection',
                wallCollision,
                'Should detect wall collisions'
            );
            
            // Test self collision
            this.game.snake.trail = [{x: 1, y: 1}, {x: 1, y: 2}, {x: 1, y: 3}];
            const selfCollision = this.game.checkCollision({x: 1, y: 2});
            this.assertTest(
                'Self Collision Detection',
                selfCollision,
                'Should detect self collisions'
            );
        } catch (error) {
            this.logTestFailure('Collision Detection', error);
        }
    }

    async testFoodSystem() {
        try {
            this.game.resetGame();
            
            // Test food placement
            const foodsExist = this.game.foods.apples.length > 0 && this.game.foods.poisons.length > 0;
            this.assertTest(
                'Food Placement',
                foodsExist,
                'Should place both apples and poisons'
            );
        } catch (error) {
            this.logTestFailure('Food System', error);
        }
    }

    async testEnergySystem() {
        try {
            this.game.resetGame();
            const initialEnergy = this.game.energy;
            
            // Move snake to consume energy
            this.game.moveSnake();
            const energyDecreased = this.game.energy < initialEnergy;
            
            this.assertTest(
                'Energy Consumption',
                energyDecreased,
                'Energy should decrease with movement'
            );
        } catch (error) {
            this.logTestFailure('Energy System', error);
        }
    }

    async testAIBehavior() {
        try {
            this.game.resetGame();
            this.game.isAIEnabled = true;
            
            // Test AI decision making
            const direction = this.game.decideNextMove();
            const validDirections = ['up', 'down', 'left', 'right'];
            
            this.assertTest(
                'AI Decision Making',
                validDirections.includes(direction),
                'AI should make valid movement decisions'
            );
        } catch (error) {
            this.logTestFailure('AI Behavior', error);
        }
    }

    // Helper methods
    validateMazeWalls(maze) {
        // Check outer walls
        for (let i = 0; i < maze.length; i++) {
            if (maze[0][i] !== 1 || maze[maze.length-1][i] !== 1) return false;
            if (maze[i][0] !== 1 || maze[i][maze.length-1] !== 1) return false;
        }
        return true;
    }

    verifyMovement(oldPos, newPos, direction) {
        switch(direction) {
            case 'up': return newPos.y === oldPos.y - 1;
            case 'down': return newPos.y === oldPos.y + 1;
            case 'left': return newPos.x === oldPos.x - 1;
            case 'right': return newPos.x === oldPos.x + 1;
            default: return false;
        }
    }

    assertTest(name, condition, message) {
        if (condition) {
            this.testResults.passed++;
            this.testResults.tests.push({
                name,
                status: 'PASSED',
                message
            });
        } else {
            this.testResults.failed++;
            this.testResults.tests.push({
                name,
                status: 'FAILED',
                message
            });
        }
    }

    logTestFailure(testName, error) {
        this.testResults.failed++;
        this.testResults.tests.push({
            name: testName,
            status: 'ERROR',
            message: error.message
        });
    }

    reportResults() {
        console.log('\nTest Results:');
        console.log(`Passed: ${this.testResults.passed}`);
        console.log(`Failed: ${this.testResults.failed}`);
        console.log('\nDetailed Results:');
        this.testResults.tests.forEach(test => {
            console.log(`${test.status}: ${test.name} - ${test.message}`);
        });
    }
}

// Expose GameTester to window
if (typeof window !== 'undefined') {
    window.GameTester = GameTester;
} 